package com.pig4cloud.pig.ads.gdt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.ads.config.SdkProperties;
import com.pig4cloud.pig.ads.gdt.service.GdtAccesstokenService;
import com.pig4cloud.pig.ads.gdt.service.GdtChannelPackageService;
import com.pig4cloud.pig.ads.pig.mapper.gdt.GdtChannelPackageMapper;
import com.pig4cloud.pig.ads.utils.OEHttpUtils;
import com.pig4cloud.pig.api.entity.GdtChannelPackage;
import com.pig4cloud.pig.api.entity.ResponseBean;
import com.pig4cloud.pig.api.enums.GdtChannelPackageEnum;
import com.pig4cloud.pig.api.util.MapUtils;
import com.pig4cloud.pig.api.vo.GdtChannelPackageReq;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author cx
 * @version 1.0.0
 * @ClassName GdtChannelPackageServiceImpl.java
 * @createTime 2021年07月12日 20:35:00
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class GdtChannelPackageServiceImpl extends ServiceImpl<GdtChannelPackageMapper, GdtChannelPackage> implements GdtChannelPackageService {

	private final GdtAccesstokenService gdtAccesstokenService;
	private final SdkProperties sdkProperties;

	/**
	 * 广点通上传视频接口地址前缀
	 */
	@Value(value = "${gdt_url}")
	private String gdtUrl;
	/**
	 * 上传渠道包
	 * @param record
	 * @return
	 */
	@Override
	public R create(GdtChannelPackage record){
		// 验证数据
		if (Objects.isNull(record.getAdId())){
			return R.failed("关联ID不能为空");
		}
		if (StringUtils.isBlank(record.getAdAccount())){
			return R.failed("广告账户不能为空");
		}
		if (StringUtils.isBlank(record.getUnionAppId())){
			return R.failed("APPID不能为空");
		}
		if (StringUtils.isBlank(record.getPackageName())){
			return R.failed("渠道包名称不能为空");
		}
		if (StringUtils.isBlank(record.getPackageOriginUrl())){
			return R.failed("渠道包下载url不能为空");
		}
		if (record.getPackageOriginUrl().toLowerCase().indexOf(".apk") < 0){
			return R.failed("渠道包下载url必须以.apk后缀结尾");
		}

		record.setCreateTime(new Date());
		record.setUpdateTime(new Date());
		// 保存信息
		if (!SqlHelper.retBool(this.getBaseMapper().insert(record))){
			return R.failed("同步到投放平台后，保存失败");
		}
		// 调用接口上传渠道包
		R result = this.synGdtChannelPackage(record);

		// 更新信息
		if (!SqlHelper.retBool(this.getBaseMapper().updateById(record))){
			return R.failed("同步到投放平台后，更新失败");
		}
		return result;
	}

	public R synGdtChannelPackage(GdtChannelPackage entity){
		//公共方法获取accessToken
		Map<String, String> map = gdtAccesstokenService.fetchAccesstoken(entity.getAdAccount());
		String url = gdtUrl + "android_union_channel_packages/add" + "?" + MapUtils.queryString(map);

		Map<String,Object> param = new HashMap<>();
		param.put("account_id",entity.getAdAccount());
		param.put("android_union_app_id",entity.getUnionAppId());
		param.put("package_name",entity.getPackageName());
		param.put("package_origin_url",entity.getPackageOriginUrl());
		param.put("customized_channel_id",entity.getCustomizedChannelId());
		//调第三方平台（广点通）接口
		String resultStr = OEHttpUtils.doPost(url, param);
		ResponseBean resBean = JSON.parseObject(resultStr, ResponseBean.class);
		if (resBean != null && "0".equals(resBean.getCode())) {
			//同步修改数据库
			JSONObject jsonData = resBean.getData();
			String channelPackageId = jsonData.getString("app_android_channel_package_id");
			String packageStatus = jsonData.getString("package_status");
			entity.setChannelPackageId(channelPackageId.substring(channelPackageId.indexOf(";")+1,channelPackageId.length()));
			entity.setPackageStatus(packageStatus);
			entity.setPackageSynMsg(GdtChannelPackageEnum.getName(packageStatus));
			return R.ok(entity);
		}else if(resBean != null){
			return R.failed(resBean.getMessage());
		}
		return R.failed("调用广点通接口异常");
	}
	/**
	 * 获取渠道包列表
	 * @param record
	 * @return
	 */
	@Override
	public R getList(GdtChannelPackage record){
		QueryWrapper<GdtChannelPackage> wrapper = new QueryWrapper<>();
		wrapper.eq("union_app_id",record.getUnionAppId());
		wrapper.eq("package_status","CHANNEL_PACKAGE_STATUS_PASSED");
		if(StringUtils.isNotBlank(record.getPackageName())) {
			wrapper.like("package_name", record.getPackageName());
		}
		wrapper.groupBy("channel_package_id");
		wrapper.orderByDesc("create_time");
		List<GdtChannelPackage> list=new ArrayList<>();
		if(StringUtils.isBlank(record.getPackageName())){
			record.setChannelPackageId("0");
			record.setPackageName("主线包");
			list.add(record);
		}
		list.addAll(this.list(wrapper));
		return R.ok(list);
	}
	/**
	 * 根据advertiser_monitor_info主键获取列表
	 * @param record
	 * @return
	 */
	@Override
	public R getPackageList(GdtChannelPackageReq record){
		List<GdtChannelPackage> gdtChannelPackageList = this.list(Wrappers.<GdtChannelPackage>lambdaQuery()
				.in(CollectionUtils.isNotEmpty(record.getAdIds()), GdtChannelPackage::getAdId, record.getAdIds())
				.in(CollectionUtils.isNotEmpty(record.getAppChlList()), GdtChannelPackage::getAppChl, record.getAppChlList()));
		return R.ok(gdtChannelPackageList);
	}

	@Override
	public R extendPackage(GdtChannelPackageReq record){
		List<String> addAppChl = Lists.newArrayList();
		List<String> updateAppChl = Lists.newArrayList();
		List<String> appChl = record.getAppChlList();
		// 获取渠道编码是否已经创建，以盘古库为准
		List<GdtChannelPackage> channelPackageList = this.list(Wrappers.<GdtChannelPackage>lambdaQuery().in(GdtChannelPackage::getAppChl, appChl));
		for (String app : appChl){
			List<String> channelPackages = channelPackageList.stream().map(GdtChannelPackage::getAppChl).collect(Collectors.toList());
			if (channelPackages.contains(app)){
				updateAppChl.add(app);
			}else{
				addAppChl.add(app);
			}
		}
		String errorMsg = "";
		if (CollectionUtils.isNotEmpty(addAppChl)){
			// 创建应用分包
			R result = this.extendPackageAdd(record, addAppChl);
			if (0 != result.getCode()){
				errorMsg += result.getMsg();
			}
		}
		if (CollectionUtils.isNotEmpty(updateAppChl)){
			// 更新应用分包
			R result = this.extendPackageUpdate(record, updateAppChl);
			if (0 != result.getCode()){
				errorMsg += result.getMsg();
			}
		}
		return StringUtils.isBlank(errorMsg) ? R.ok() : R.failed(errorMsg);
	}

	/**
	 * 创建应用分包
	 * @param record
	 * @return
	 */
	public R extendPackageAdd(GdtChannelPackageReq record, List<String> appChl){
		//公共方法获取accessToken
		Map<String, String> map = gdtAccesstokenService.fetchAccesstoken(record.getAdAccount());
		String url = gdtUrl + sdkProperties.getGdtExtendPackageAdd() + "?" + MapUtils.queryString(map);
		// 调用广点通创建应用分包
		try {
			Map<String, Object> data = new HashMap<>();
			data.put("account_id", record.getAdAccount());
			data.put("package_id", record.getUnionAppId());

			List<Map<String, String>> channel_list = Lists.newArrayList();
			for (String packCode : appChl){
				Map<String, String> channel_map = new HashMap<>();
				channel_map.put("channel_id", packCode);
				channel_map.put("channel_name", packCode);
				channel_list.add(channel_map);
			}
			data.put("channel_list", channel_list);

			log.info(">>>广点通创建应用分包param:{}", JSON.toJSONString(data));
			String result = OEHttpUtils.doPost(url, data);
			log.info(">>>广点通创建应用分包result:{}", result);
			// {"code":0,"data":{"failed_results":[],"package_id":2000000264,"success_results":[{"channel_name":"2000000264_11x22x33x44","channel_package_id":3699369,"message":""}]},"message":"","message_cn":""}
			// {"code":0,"data":{"failed_results":[{"channel_name":"2000000264_1x2x3x4","channel_package_id":0,"message":"该应用下已存在相同渠道名称(2000000264_1x2x3x4)的渠道包:channel_package_id:3697935"},{"channel_name":"2000000264_1x2x3x4","channel_package_id":0,"message":"该应用下已存在相同渠道标识(1x2x3x4)的渠道包:channel_package_id:3697935"}],"package_id":2000000264,"success_results":[]},"message":"","message_cn":""}
			ResponseBean resBean = JSON.parseObject(result, ResponseBean.class);
			if (null != resBean && "0".equals(resBean.getCode())) {
				List<GdtChannelPackage> packageList = Lists.newArrayList();
				JSONObject jsonObject = resBean.getData();
				JSONArray arraySuccess = jsonObject.getJSONArray("success_results");
				JSONArray arrayFailed = jsonObject.getJSONArray("failed_results");

				// 成功的分包 保存到数据库
				if (CollectionUtils.isNotEmpty(arraySuccess)){
					for (Object object : arraySuccess){
						JSONObject jsonObjectSuccess = JSONObject.parseObject(JSON.toJSONString(object));
						GdtChannelPackage channelPackage = new GdtChannelPackage();
						channelPackage.setAdAccount(record.getAdAccount());
						channelPackage.setUnionAppId(record.getUnionAppId());
						String channel_name = jsonObjectSuccess.getString("channel_name");
						String channel_package_id = jsonObjectSuccess.getString("channel_package_id");
						channelPackage.setPackageName(channel_name);
						channelPackage.setAppChl(channel_name);
						channelPackage.setChannelPackageId(channel_package_id);
						channelPackage.setCustomizedChannelId(channel_name);
						channelPackage.setPackageStatus(GdtChannelPackageEnum.CHANNEL_PACKAGE_STATUS_REVIEWING.getValue());
						channelPackage.setCreateTime(new Date());
						packageList.add(channelPackage);
					}
				}

				if (CollectionUtils.isNotEmpty(packageList)){
					this.saveBatch(packageList);
				}

				// 失败的分包 返回提示
				if (CollectionUtils.isNotEmpty(arrayFailed)){
					String msg = "";
					for (Object object : arrayFailed){
						JSONObject jsonObjectFailed = JSONObject.parseObject(JSON.toJSONString(object));
						String message = jsonObjectFailed.getString("message");
						if (message.indexOf("相同渠道") > 0){
							msg += "[" + jsonObjectFailed.getString("message") + "]";
						}
					}
					return StringUtils.isNotBlank(msg) ? R.failed(msg) : R.failed();
				}
			}else{
				log.error(">>>广点通创建应用分包异常:{}", resBean.getMessage());
				return R.failed(resBean.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return R.ok();
	}
	/**
	 * 更新应用分包
	 * @param record
	 * @return
	 */
	public R extendPackageUpdate(GdtChannelPackageReq record, List<String> appChl){
		//公共方法获取accessToken
		Map<String, String> map = gdtAccesstokenService.fetchAccesstoken(record.getAdAccount());
		String url = gdtUrl + sdkProperties.getGdtExtendPackageUpdate() + "?" + MapUtils.queryString(map);
		// 调用广点通创建应用分包
		try {
			Map<String, Object> data = new HashMap<>();
			data.put("account_id", record.getAdAccount());
			data.put("package_id", record.getUnionAppId());

			List<Map<String, String>> channel_list = Lists.newArrayList();
			for (String packCode : appChl){
				Map<String, String> channel_map = new HashMap<>();
				channel_map.put("channel_id", packCode);
				channel_list.add(channel_map);
			}
			data.put("channel_list", channel_list);

			log.info(">>>广点通更新应用分包param:{}", JSON.toJSONString(data));
			String result = OEHttpUtils.doPost(url, data);
			log.info(">>>广点通更新应用分包result:{}", result);
			// {"code":0,"data":{"failed_results":[],"package_id":2000000264,"success_results":[{"channel_name":"2000000264_11x22x33x44","channel_package_id":3699369,"message":""}]},"message":"","message_cn":""}
			// {"code":0,"data":{"failed_results":[{"channel_name":"2000000264_1x2x3x4","channel_package_id":0,"message":"该应用下已存在相同渠道名称(2000000264_1x2x3x4)的渠道包:channel_package_id:3697935"},{"channel_name":"2000000264_1x2x3x4","channel_package_id":0,"message":"该应用下已存在相同渠道标识(1x2x3x4)的渠道包:channel_package_id:3697935"}],"package_id":2000000264,"success_results":[]},"message":"","message_cn":""}
			ResponseBean resBean = JSON.parseObject(result, ResponseBean.class);
			if (null != resBean && "0".equals(resBean.getCode())) {
				JSONObject jsonObject = resBean.getData();
				JSONArray arraySuccess = jsonObject.getJSONArray("success_results");
				JSONArray arrayFailed = jsonObject.getJSONArray("failed_results");

				List<String> channel_package_ids = Lists.newArrayList();
				if (Objects.nonNull(arraySuccess) && CollectionUtils.isNotEmpty(arraySuccess)){
					for (Object object : arraySuccess){
						JSONObject jsonObjectSuccess = JSONObject.parseObject(JSON.toJSONString(object));
						channel_package_ids.add(jsonObjectSuccess.getString("channel_package_id"));
					}
				}
				// 更新包状态重置为再次审核中
				if (CollectionUtils.isNotEmpty(channel_package_ids)){
					LambdaUpdateWrapper<GdtChannelPackage> wrapper = new LambdaUpdateWrapper<>();
					wrapper.set(GdtChannelPackage::getPackageStatus, GdtChannelPackageEnum.CHANNEL_PACKAGE_STATUS_REVIEWING_AGAIN.getValue());
					wrapper.in(GdtChannelPackage::getChannelPackageId, channel_package_ids);
					this.update(wrapper);
				}

				// 失败的分包 返回提示
				if (Objects.nonNull(arrayFailed) && CollectionUtils.isNotEmpty(arrayFailed)){
					JSONObject jsonObjectFailed = arrayFailed.getJSONObject(0);
					String message = jsonObjectFailed.getString("message");
					return R.failed("[" + message + "]");
				}
			}else{
				log.error(">>>广点通更新应用分包异常:{}", resBean.getMessage());
				return R.failed(resBean.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return R.ok();
	}
}
